// =======================================================================
// 
//       Filename:  parser.hpp
// 
//    Description:  
// 
//        Version:  1.0
//        Created:  25.03.2010 21:18:50
//       Revision:  none
//       Compiler:  g++
// 
//         Author:  Dominik 'domachine' Burgdörfer (-), dominik.burgdoerfer@googlemail.com
//        Company:  -
// 
// =======================================================================


#ifndef  PARSER_INC
#define  PARSER_INC
#include <stdexcept>
#include <map>
#include <list>
#include "syntaxerror.hpp"
#include "citerator.hpp"
#include "template/file.hpp"
#include "template/scriptelement.hpp"
#include "template/varelement.hpp"
#include "types/string.hpp"

namespace webplodder {
    

    /**
     * This class parses a template file
     * and interprets commands and scripts on the fly.
     * @brief This class parses a template file.
     */
    class Parser {
    public:
        // Types
        enum CacheMode {
            CACHE_NOTHING,
            CACHE_SCRIPT,
            CACHE_ALL
        };

    public:
        Parser();

        /**
         * @brief Launches the parsing process.
         * @throw std::logic_error Thrown if a script is detected
         *                         and no rule defined
         * @throw SyntaxError Thrown if an syntax error is detected.
         */
        void parse(Template::File& templateFile);

        CIterator* iterator();

        /**
         * @brief Sets the current cache mode.
         */
        void setCacheMode(CacheMode mode);

    private:
        void safelyIncr();
        void skipWhiteSpace();
        boost::shared_ptr<Template::ScriptElement> parseScript(
                Template::File& templateFile);
        boost::shared_ptr<Template::VarElement> parseVar(
                Template::File& templateFile);
        boost::shared_ptr<Template::Element> 
            parseCmd(Template::File& templateFile);
        boost::shared_ptr<types::String>
            parseString();
        boost::shared_ptr<types::Object>
            parseNumber();

        CIterator mIterator;
        int mLine;
        CacheMode mCacheMode;
    };
}
#endif   // ----- #ifndef PARSER_INC  -----
